/*
	版权所有 2009-2023 荆门泽优软件有限公司
	保留所有权利
	产品首页：http://www.ncmem.com/webapp/up2/index.aspx
	控件下载：http://www.ncmem.com/webapp/up2/pack.aspx
	示例下载：http://www.ncmem.com/webapp/up2/versions.aspx
	联系信箱：1085617561@qq.com
	联系QQ：1085617561
    版本：1.3
    更新记录：
        2023-03-05 完善逻辑
        2016-03-07 优化业务逻辑
        2015-08-01 优化
	    2009-11-05 创建
*/

function HttpUploaderMgr()
{
    //根路径：http://localhost:8888/
    var root = [
        window.location.protocol,
        "//",
        window.location.host,
        "/api/up2/"
    ].join("");

    //url=>res/
    //http://localhost:8888/filemgr/res/up6/up6.js=>
    this.getJsDir = function () {
        var js = document.scripts;
        var jsPath;
        for (var i = 0; i < js.length; i++) {
            if (js[i].src.indexOf("up2-single.js") > -1) {
                jsPath = js[i].src.substring(0, js[i].src.indexOf("up2-single.js"));
            }
        }
        return jsPath;
    };
    //http://localhost/res/down2/
    var pathRes = this.getJsDir() + "imgs/";

    var _this = this;
    this.Config = {
          "EncodeType"                : "GB2312"
		, "Company"                   : "荆门泽优软件有限公司"
		, "Version"                   : "2,5,54,51373"
		, "License"                   : ""
		, "Debug"                     : false//调试开关
		, "LogFile"                   : "C:\\log.txt"//日志文件路径
		, "FileFilter"                : "*"//文件类型。所有类型：*。自定义类型：jpg,bmp,png,gif,rar,zip,7z,doc
	    //字节计算器：http                  ://www.beesky.com/newsite/bit_byte.htm
	    //超过10MB建议选择HttpUploader6：http://www.ncmem.com/webplug/http-uploader6/index.asp
		, "FileSizeLimit"             : "2147483648"//自定义允许上传的文件大小，以字节为单位。0表示不限制。字节计算工具：http://www.beesky.com/newsite/bit_byte.htm
		, "AllowMultiSelect"          : false//多选开关。true:开启多选。false:关闭多选
		, "CryptoType"                : "md5"//文件校验方式：md5,crc,sha1
        , "InitDir"                   : ""//初始化路径。示例：D:\\Soft
		, "Compress"		          : ""//是否开启压缩。值：zip
		, "FileFieldName"	          : "file"//文件字段名称
		, "Cookie"	                  : ""//cookie
		, "PostUrl"                   : "http://localhost:811/up2/upload.php"
	    //x86
        , ie: {
            drop: { clsid: "4D2454F8-EB25-465f-B867-C2A3E9F3D4B4", name: "Xproer.HttpDroper2" }
            , part: { clsid: "6F3EB4AF-FC9C-4570-A686-88B4B427C6FE", name: "Xproer.HttpPartition2" }
            , path: "http://www.ncmem.com/download/up2/up2.cab"
        }
	    //x64
        , ie64: {
            drop: { clsid: "C9388115-887C-4d64-B175-F8F1AA5437BF", name: "Xproer.HttpDroper2x64" }
            , part: { clsid: "3AFFCB6D-55ED-4ada-A1EC-D7D87BA29E51", name: "Xproer.HttpPartition2x64" }
            , path: "http://www.ncmem.com/download/up2/up64.cab"
        }
        , firefox: { name: "", type: "application/npHttpUp2", path: "http://www.ncmem.com/download/up2/up2.xpi" }
        , chrome: { name: "npHttpUp2", type: "application/npHttpUp2", path: "http://www.ncmem.com/download/up2/up2.crx" }
        , edge: { protocol: "up2", port: 9300, visible: false }
        , exe: { path: "http://www.ncmem.com/download/up2/up2.exe" },
        Fields: {
            "uname": "test"
            , "upass": "test"
            , "uid": "0"
            , "fid": "0"
        },
        state:{
            Ready: 0,
            Posting: 1,
            Stop: 2,
            Error: 3,
            GetNewID: 4,
            Complete: 5,
            WaitContinueUpload: 6,
            None: 7,
            Waiting: 8,
            MD5Working: 9
        },
        error:{
            "0": "发送数据错误",
            "1": "接收数据错误",
            "2": "域名未授权",
            "3": "公司未授权",
            "4": "访问本地文件错误",
            //md5
            "200": "无打打开文件",
            "201": "文件大小为0"
        }
    };
    this.data = {
        browser: { name: navigator.userAgent.toLowerCase(), ie: true, ie64: false, firefox: false, chrome: false, edge: false, arm64: false, mips64: false },
        cmps: [], file: null/**当前上传项 */
    };
    this.ui = {
        render: null,
        panel: null,//
        toolbar:null,
        btn: {
            selFile: null,
            selFolder: null,
            paste: null,
            clear: null,
            post: null,
            stop: null,
            setup: null,
            setupCmp: null
        },
        ico: {
			ok: pathRes + "16/ok.png",
			setup: pathRes + "16/setup.png",
			file: pathRes + "32/file.png",
			del: pathRes + "32/del.png",
			post: pathRes + "32/post.png",
			stop: pathRes + "32/stop.png"
        }
    };

    this.event = {
        postProcess: function (obj, speed, postedLength, percent, times) { },
        postComplete: function (obj) { },
        postError: function (obj) { },
        selFile: function () { }
    };

    this.ieParter = null;
    this.parter = null;//
    this.fileItem = null;//jquery object
    this.nat_loaded = false;
	this.pluginInited = false;

    //检查版本 Win32/Win64/Firefox/Chrome
    this.data.browser.ie = this.data.browser.name.indexOf("msie") > 0;
    //IE11检查
    this.data.browser.ie = this.data.browser.ie ? this.data.browser.ie : this.data.browser.name.search(/(msie\s|trident.*rv:)([\w.]+)/) != -1;
    this.data.browser.firefox = this.data.browser.name.indexOf("firefox") > 0;
    this.data.browser.chrome = this.data.browser.name.indexOf("chrome") > 0;
    this.data.browser.mips64 = this.data.browser.name.indexOf("mips64") > 0;
    this.data.browser.arm64 = this.data.browser.name.indexOf("aarch64") > 0;
    this.data.browser.edge = this.data.browser.name.indexOf("edge") > 0;
    if (this.data.browser.edge) { this.data.browser.ie = this.data.browser.firefox = this.data.browser.chrome = this.data.browser.chrome45 = false; }

    this.edgeApp = new WebServer(this);
    this.app = up2_app;
    this.app.edgeApp = this.edgeApp;
    this.app.Config = this.Config;
    this.app.ins = this;

    if (arguments.length > 0) {
        var par = arguments[0];
        if (typeof (par.config) != "undefined") $.extend(true, this.Config, par.config);
        if (typeof (par.event) != "undefined") $.extend(true, this.event, par.event);
        if (typeof (par.ui) != "undefined") $.extend(true, this.ui, par.ui);
    }
    //浏览器环境检查
    if (this.data.browser.ie)
    {
        //Win64
        if (window.navigator.platform == "Win64")
        {
	        $.extend(this.Config.ie, this.Config.ie64);
        }
    }
    else if (this.data.browser.firefox)
    {
        this.data.browser.edge = true;
        this.app.postMessage = this.app.postMessageEdge;
        this.edgeApp.run = this.edgeApp.runChr;
    } //Chrome
    else if (this.data.browser.chrome)
    {
        this.data.browser.edge = true;
        this.app.check = this.app.checkFF;
        $.extend(this.Config.firefox, this.Config.chrome);
        this.app.postMessage = this.app.postMessageEdge;
        this.edgeApp.run = this.edgeApp.runChr;
    }
    else if (this.data.browser.edge)
    {
        this.app.postMessage = this.app.postMessageEdge;
    }

    this.part_files = function (ret)
    {
        if (ret.files == null) return;
        var f = ret.files[0];
        this.addFileLoc(f);
    };
    this.post_complete = function (ret)
    {
        this.data.file.postComplete();
        this.event.postComplete(this.data.file);
        this.data.file = null;
    };
    this.post_error = function (ret)
    {
        if (ret.value == "12")
        {
            this.setupTip();
            return;
        }
        if (ret.value == "2")
        {
            alert(this.Config.error[ret.code]);
            return;
        }
        var f = this.data.file;
        f.postError(ret);
        this.event.postError(this.data.file);
    };
    this.post_process = function (ret)
    {
        var f = this.data.file;
        f.postProcess(ret);
    };
    this.queue_complete = function (ret)
    {
    };
    this.plugin_loaded = function (arg) { this.nat_loaded = true; };
    this.load_complete = function (json) {
        this.pluginInited = true;
        var needUpdate = true;

        this.ui.btn.setup.hide();
        this.ui.btn.setupCmp.hide();
        if (typeof (json.version) != "undefined") {
            if (json.version == this.Config.Version) {
                needUpdate = false;
            }
        }
        if (needUpdate) this.update_notice();
        //else { this.btnSetup.hide(); }
    };
    this.load_complete_edge = function (json) {
		this.pluginInited = true;
        _this.app.init();
    };
    this.recvMessage = function (str)
    {
        var ret = JSON.parse(str);
        if (ret.name == "part_files") _this.part_files(ret);
        else if (ret.name == "post_complete") _this.post_complete(ret);
        else if (ret.name == "post_process") _this.post_process(ret);
        else if (ret.name == "post_error") _this.post_error(ret);
        else if (ret.name == "queue_complete") _this.queue_complete(ret);
        else if (ret.name == "plugin_loaded") _this.plugin_loaded(ret);
        else if (ret.name == "load_complete") { _this.load_complete(ret); }
        else if (ret.name == "load_complete_edge") { _this.load_complete_edge(ret); }
    };

    //文件上传面板。
    this.GetHtml = function ()
    {
        //加载拖拽控件
	    var acx = '<embed name="ffParter" type="' + this.Config.firefox.type + '" pluginspage="' + this.Config.firefox.path + '" width="1" height="1"/>';
        if (this.chrome45) acx = "";
        if (this.ie) {
            //文件上传控件
            acx = '<object name="ieParter" classid="clsid:' + this.Config.ie.part.clsid + '"';
            acx += ' codebase="' + this.Config.ie.path + '#version=' + this.Config["Version"] + '" width="1" height="1" ></object>';
        }

        //上传列表项ui
        acx += '<div class="file-item" name="fileItem">\
                    <div class="img-box"><img name="file"/></div>\
					<div class="area-l">\
						<div class="file-head">\
						    <div name="fileName" class="name">HttpUploader程序开发.pdf</div>\
						    <div name="percent" class="percent">(35%)</div>\
						    <div name="fileSize" class="size" child="1">1000.23MB</div>\
                        </div>\
						<div class="process-border"><div name="process" class="process"></div></div>\
						<div name="msg" class="msg top-space">15.3MB 20KB/S 10:02:00</div>\
					</div>\
					<div class="area-r">\
                        <span class="btn-box" name="cancel" title="取消"><img name="stop"/><div>取消</div></span>\
                        <span class="btn-box hide" name="post" title="继续"><img name="post"/><div>继续</div></span>\
						<span class="btn-box hide" name="stop" title="停止"><img name="stop"/><div>停止</div></span>\
						<span class="btn-box hide" name="del" title="删除"><img name="del"/><div>删除</div></span>\
					</div>\
		        </div>\
                <div name="toolbar" class="toolbar">\
                    <span class="btn-default" name="btnSetup"><img name="setup"/>安装控件</span>\
                    <span class="btn-default" name="btnSetupCmp"><img name="ok"/>我已安装</span>\
                </div>\
                ';
        return acx;
    };

    this.setupTip = function ()
    {
        var dom = $(document.body).append('<a href="' + this.Config["ExePath"] + '">请安装控件</a>');
        dom.css("cursor", "pointer");
    };

    this.loadAuto = function ()
    {
        var html = this.GetHtml();
        var dom = $(document.body).append(html);
        this.initUI(dom);
    };

    //加载容器，上传面板，文件列表面板
    this.loadTo = function (o)
    {
        this.ui.panel = o;
        var html = this.GetHtml();
        var dom = o.html(html);
        this.initUI(dom);
    };

    this.initUI = function (ui)
    {
        this.fileItem = ui.find('div[name="fileItem"]');
        this.ieParter = ui.find('object[name="ieParter"]').get(0);
        this.parter = ui.find('embed[name="ffParter"]').get(0);
        this.ui.toolbar = ui.find(".toolbar");
        this.ui.btn.setup = ui.find("span[name='btnSetup']");
        this.ui.btn.setupCmp = ui.find("span[name='btnSetupCmp']");
        this.ui.btn.setup.click(function () { window.open(_this.Config.exe.path); });
        this.ui.btn.setupCmp.click(function () { _this.edgeApp.connect(); });
        this.ui.toolbar.find(".btn-default").each(function () {
            $(this).hover(function () {
                $(this).addClass("btn-hover");
            }, function () {
                $(this).removeClass("btn-hover");
            });
        });
        //更新图标
        $.each(this.ui.ico, function (i, n) {
            ui.find("img[name=\"" + i + "\"]").attr("src", n);
        });

        $(function () {
            if (!_this.data.browser.edge) {
                if (_this.data.browser.ie) {
                    _this.parter = _this.ieParter;
                }
                _this.parter.StateChanged = _this.recvMessage;
            }

            if (_this.data.browser.edge) {
                _this.edgeApp.connect();
            }
            else {
                _this.app.init();
            }
        });
    };

    this.pluginLoad = function () {
        if (!this.pluginInited) {
            if (this.edge) {
                this.edgeApp.connect();
            }
        }
    };
    this.pluginCheck = function () {
        if (!this.pluginInited) {
            alert("控件没有加载成功，请安装控件或等待加载。");
            this.pluginLoad();
            return false;
        }
        return true;
    };

    //APIs
    this.openFile = function ()
    {
        if (!this.pluginCheck()) return;
        this.ui.panel.empty();
        _this.app.openFile();
    };
	this.openFolder = function(){
		if( !this.pluginCheck() ) return;
		this.app.openFolder();
	};
    //粘贴文件
    this.pasteFile = function ()
    {
		if( !this.pluginCheck() ) return;
        _this.app.pasteFiles();
    };
    //oid,显示上传项的层ID
    this.postAuto = function (oid)
    {
        if (this.data.file != null) return;
        if(typeof(oid)=="string")
        {
            if(oid.indexOf("#")==-1)
            {
                this.ui.panel = $("#" + oid);
            }
            else{
                this.ui.panel = $(oid);
            }
        }
        else{
            this.ui.panel=oid;
        }
        this.ui.panel.empty();
        this.openFile();
    };

    //oid,显示上传项的层ID
    this.openFolder = function (oid) {
        if (this.data.file != null) return;
        this.ui.panel = $("#" + oid);
		if( !this.pluginCheck() ) return;
        _this.app.openFolder();
    };

    //上传文件
    this.postLoc = function (filePath, oid)
    {
        if (this.data.file != null) return;
        this.ui.panel = $("#" + oid);
		if( !this.pluginCheck() ) return;
        this.app.addFile({ path: filePath });
    };
    this.addFileLoc = function (f)
    {
        var uper = new FileUploader(f, this);
        this.data.file = uper;
        var ui = this.fileItem.clone(true);
        ui.css("display", "block");
        this.ui.panel.append(ui);

        var uiName      = ui.find("div[name='fileName']");
        var uiSize      = ui.find("div[name='fileSize']")
        var divProcess  = ui.find("div[name='process']");
        var divMsg      = ui.find("div[name='msg']");
        var btnCancel   = ui.find("span[name='cancel']");
        var btnDel      = ui.find("span[name='del']");
        var divPercent  = ui.find("div[name='percent']");
        var ui_eles     = { msg: divMsg, percent: divPercent, process: divProcess, btn: { cancel: btnCancel, del: btnDel }, panel: ui};

        uper.ui = ui_eles;

        uiName.text(f.name).attr("title", f.name);
        uiSize.text(f.size);
        divMsg.text("");
        divPercent.text("(0%)");
        btnCancel.click(function ()
        {
            var obj = $(this);
            switch (obj.text())
            {
                case "暂停":
                case "停止":
                    uper.stop();
                    uper.remove();
                    break;
                case "取消":
                    {
                        uper.stop();
                        uper.remove();
                    }
                    break;
                case "续传":
                case "重试":
                    uper.Post();
                    break;
            }
        });
        btnCancel.hide();
        btnDel.click(function () { uper.remove(); _this.data.file = null;});

        uper.ready(); //准备
        this.event.selFile();
        setTimeout(function(){ _this.app.queuePost(); }, 500);
    };

    //加载
    if (typeof (this.ui.render) == "string") {
        $(function () {
            _this.loadTo($("#" + _this.ui.render));
        })
    }
    else if (typeof (this.ui.render) == "object") {
        this.loadTo(this.ui.render);
    }
}

//文件上传对象
function FileUploader(f, mgr)
{
    var _this = this;
    this.Manager = mgr; //上传管理器指针
    this.Config = mgr.Config;
    this.Fields = mgr.Fields;
    this.ActiveX = mgr.ActiveX;
    this.browser = mgr.browser;
    this.firefox = mgr.firefox;
    this.chrome = mgr.chrome;
    this.State = this.Config.state.None;
    this.fileLoc = f;
    this.ui = { msg: null, percent: null, process: null, btn: { cancel: null, del: null }, spliter: null, panel: null };

    //准备
    this.ready = function ()
    {
        this.ui.msg.text("正在上传队列中等待");
        this.State = this.Config.state.Ready;
    };

    this.stop = function ()
    {
        var inf = { name: "file_cancel", id: this.fileLoc.id };
        this.app.stop(inf);
    };

    //从上传列表中删除
    this.remove = function ()
    {
        //删除信息层
        this.ui.panel.remove();
    };

    this.postError = function (json)
    {
        this.ui.msg.text(this.Config.error[json.code]);
        this.ui.btn.stop.hide();
        this.ui.btn.post.show();
        this.ui.btn.del.show();
        this.ui.percent.text("(0%)");
        this.ui.process.css("width", "0");
    };

    this.postComplete = function ()
    {
        $.each(this.ui.btn, function (i, n) {
            n.hide();
        });
        this.ui.process.css("width", "100%");
        this.ui.percent.text("(100%)");
        this.ui.msg.text("上传完成");
        this.State = this.Config.state.Complete;
    };

    this.postProcess = function (json)
    {
        var msg = "" + json.len + " " + json.speed + " " + json.time;
        this.ui.msg.text(msg);
        this.ui.percent.text("("+json.percent+")");
        this.ui.process.css("width", json.percent);
    };
}
